package com.cskaoyan.service;

import com.cskaoyan.bean.baseresultVO.BaseData;
import com.cskaoyan.bean.baseresultVO.BaseParam;
import com.cskaoyan.bean.coupon.CouponVO;
import com.cskaoyan.bean.domain.*;
import com.cskaoyan.mapper.CartMapper;
import com.cskaoyan.mapper.CouponMapper;
import com.cskaoyan.mapper.CouponUserMapper;
import com.cskaoyan.utils.MyUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.power.common.util.RandomUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.System;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @description:
 * @author:
 * @date:
 */
@Transactional
@Service
public class CouponServiceImpl implements CouponService {
    @Autowired
    CouponMapper couponMapper;
    @Autowired
    CouponUserMapper couponUserMapper;

    @Override
    public BaseData couponList(String name, Short type, Short status, BaseParam baseParam) {
        CouponExample couponExample = new CouponExample();
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());
        CouponExample.Criteria criteria = couponExample.createCriteria();
        if (!MyUtils.isEmpty(name))
            criteria.andNameLike("%" + name + "%");
        if (type != null)
            criteria.andTypeEqualTo(type);
        if (status != null) {
            criteria.andStatusEqualTo(status);
            criteria.andDeletedEqualTo(status == 2);
        }
//        else
//            criteria.andDeletedEqualTo(false);
        criteria.andStatusNotEqualTo((short) 3);
        couponExample.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        PageInfo pageInfo = new PageInfo(coupons);
        BaseData baseData = new BaseData();
        baseData.setList(coupons);
        baseData.setTotal((int) pageInfo.getTotal());
        baseData.setPages(pageInfo.getPages());
        baseData.setPage(baseParam.getPage());
        baseData.setLimit(baseParam.getLimit());
        return baseData;
    }

    @Override
    public Coupon couponRead(Integer id) {
        Coupon coupon = couponMapper.selectByPrimaryKey(id);
        return coupon;
    }

    @Override
    public BaseData listUser(Integer couponId, Integer userId, Short status, BaseParam baseParam) {
        updateCouponUserStatus();
        CouponUserExample couponUserExample = new CouponUserExample();
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        if (userId != null)
            criteria.andUserIdEqualTo(userId);
        if (status != null)
            criteria.andStatusEqualTo(status);
        if (couponId != null)
            criteria.andCouponIdEqualTo(couponId);
        criteria.andDeletedEqualTo(false);
        couponUserExample.setOrderByClause(baseParam.getSort() + " " + baseParam.getOrder());
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
        PageInfo pageInfo = new PageInfo(couponUsers);
        BaseData baseData = BaseData.getBack(baseParam.getLimit(), baseParam.getPage(), pageInfo.getPages(), (int) pageInfo.getTotal(), couponUsers);
        return baseData;
    }

    @Override
    public Coupon couponUpdate(Coupon coupon) {
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andIdEqualTo(coupon.getId());
        couponMapper.updateByExampleSelective(coupon, couponExample);
        Coupon coupon1 = couponMapper.selectByPrimaryKey(coupon.getId());
        return coupon1;
    }

    @Override
    public int couponDelete(Coupon coupon) {
        Coupon coupon1 = new Coupon();
        coupon1.setId(coupon.getId());
        coupon1.setDeleted(true);
        if (coupon.getStatus() == 2) {
            coupon1.setStatus((short) 3);
        } else
            coupon1.setStatus((short) 2);
        int affectedRow = couponMapper.updateByPrimaryKeySelective(coupon1);
        return affectedRow;
    }

    @Override
    public Coupon couponCreate(Coupon coupon) {
        if (coupon.getType() == 2) {
            String str = RandomUtil.randomString(8);
            coupon.setCode(str);
        }
        couponMapper.insertSelective(coupon);
        Coupon coupon1 = couponMapper.selectByPrimaryKey(coupon.getId());
        return coupon1;
    }

    /**
     * index 显示优惠券列表
     *
     * @return
     */
    @Override
    public List<Coupon> couponsWithOutPage() {
        updateCouponStatus();
        //优惠券列表，不显示数量为0和过期的,并且status为0
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andDeletedEqualTo(false).andTotalGreaterThan(0).andStatusEqualTo((short) 0).andTypeEqualTo((short) 0);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        return coupons;
    }

    /**
     * 根据状态和用户id获取优惠券信息
     *
     * @param status
     * @param baseParam
     * @return
     */
    @Override
    public BaseData couponListWithOutSort(Short status, BaseParam baseParam) {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        updateCouponUserStatus();
        PageHelper.startPage(baseParam.getPage(), baseParam.getLimit());
        //TODO 这里的userId要换成session里的,CouponVO这里的available不知道什么意思，并没有赋值
        List<CouponVO> couponVOS = couponMapper.couponVoList(user.getId(), status);
        PageInfo pageInfo = new PageInfo(couponVOS);
        BaseData baseData = BaseData.getBack(baseParam.getLimit(), baseParam.getPage(), pageInfo.getPages(), (int) pageInfo.getTotal(), couponVOS);
        return baseData;
    }

    /**
     * 1先根据用户获取它目前能够使用的所有优惠券，status=0，userId
     * 2根据用户获取购物车里所有的商品，userId
     * 遍历1，如果是优惠券goodsType是0，则将该对象加入到一个list，如果是1，遍历购物车商品，并且查询该商品对应的类目id是否和goodsValue相同
     * 如果相同则加入到list，如果是2，遍历购物车，看商品id是否和goodsValue相同，如果相同，加入list
     *
     * @return
     */
    @Autowired
    GoodsService goodsService;

    @Override
    public BaseData couponListWithOutSort() {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        updateCouponUserStatus();
        //TODO 需要一个购物车接口和一个商品接口
        List<CouponVO> couponVOS = couponMapper.couponVoList(user.getId(), (short) 0);
        List<CouponVO> couponVOS1 = new ArrayList<>();
        for (CouponVO couponVO : couponVOS) {
            if (couponVO.getGoodsType() == 0)
                couponVOS1.add(couponVO);
            else if (couponVO.getGoodsType() == 1) {
                List<Cart> carts = getCartGoodsById(user.getId());
                for (Cart cart : carts) {
                    Goods goods = goodsService.queryDetailById(cart.getGoodsId());
                    List<Integer> integers = Arrays.asList(couponVO.getGoodsValue());
                    if (integers.contains(goods.getCategoryId())) {
                        couponVOS1.add(couponVO);
                        break;
                    }
                }
            } else if (couponVO.getGoodsType() == 2) {
                List<Cart> carts = getCartGoodsById(user.getId());
                for (Cart cart : carts) {
                    List<Integer> integers = Arrays.asList(couponVO.getGoodsValue());
                    if (integers.contains(cart.getGoodsId())) {
                        couponVOS1.add(couponVO);
                        break;
                    }
                }
            }
        }
//        ArrayList<List<CouponVO>> lists = new ArrayList<>();
//        lists.add(couponVOS1);
//        List<CouponVO> couponVOS = couponMapper.couponVoList(user.getId(), (short) 0);
        BaseData baseData = BaseData.getBack(couponVOS1.size(), 1, 1, couponVOS1.size(), couponVOS1);
//        return new BaseData(1, lists.size(), lists.size(),1, lists);

        return baseData;
    }

    /**
     * 根据用户id查询购物车商品列表
     */
    //TODO------------
    @Autowired
    CartMapper cartMapper;

    public List<Cart> getCartGoodsById(Integer userId) {
        CartExample cartExample = new CartExample();
        cartExample.createCriteria().andUserIdEqualTo(userId).andDeletedEqualTo(false);
        List<Cart> carts = cartMapper.selectByExample(cartExample);
        return carts;
    }

    /**
     * 用户领取优惠券
     * 先要将优惠券减一，同时给用户的优惠券计算有效时间，写入到用户优惠券表
     *
     * @param couponId
     * @param
     * @return
     */
    @Override
    public int couponReceive(Integer couponId) {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        if (principals == null)
            return 501;
        Object primaryPrincipal = principals.getPrimaryPrincipal();
        User user = (User) primaryPrincipal;
        //获取优惠券的信息
        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
        //判断优惠券限领几张,以及领了几张了
        //当前优惠券领了几张了
        long count = getReceiveCoupon(user.getId(), couponId);
        if (coupon.getLimit() != 0 && count >= coupon.getLimit())
            return -1;
        //以下说明还可以领取
        //更新优惠券表，数量减一
        couponMapper.decreaseTotalById(couponId);
        int affectedRow = insertUserCoupon(coupon, user.getId(), couponId);
        return affectedRow;
    }

    @Override
    public int couponExchange(String code) {
        Subject subject = SecurityUtils.getSubject();
        User user = (User) subject.getPrincipals().getPrimaryPrincipal();
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andCodeEqualTo(code);
        //没有这个code
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        if (coupons.size() == 0)
            return -2;
        //有这个code
        Coupon coupon = coupons.get(0);
        //数量不够了
        if (coupon.getTotal() == 0) {
            return -3;
        }
        //优惠券截至日期已经过了
        if (coupon.getTimeType() == 1 && coupon.getEndTime().getTime() < new Date().getTime())
            return -4;
        long count = getReceiveCoupon(user.getId(), coupon.getId());
        if (coupon.getLimit() != 0 && count >= coupon.getLimit())
            return -1;
        //还可以领
        couponMapper.decreaseTotalById(coupon.getId());
        int affectedRow = insertUserCoupon(coupon, user.getId(), coupon.getId());
        return affectedRow;
    }

    public long getReceiveCoupon(Integer userId, Integer couponId) {
        //当前优惠券领了几张了
        CouponUserExample couponUserExample = new CouponUserExample();
        couponUserExample.createCriteria().andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
        long count = couponUserMapper.countByExample(couponUserExample);
        return count;
    }

    public int insertUserCoupon(Coupon coupon, Integer userId, Integer couponId) {
        //判断优惠券是指定天数还是指定周期
        long timeDiff;
        if (coupon.getTimeType() == 1) {
            timeDiff = coupon.getEndTime().getTime() - coupon.getStartTime().getTime();
        } else {
            timeDiff = coupon.getDays() * 24 * 60 * 60 * 1000;
        }
        // 在用户优惠券表增加截至时间
        CouponUser couponUser = new CouponUser();
        couponUser.setUserId(userId);
        couponUser.setCouponId(couponId);
        couponUser.setStartTime(new Date());
        couponUser.setEndTime(new Date(new Date().getTime() + timeDiff));
        int affectedRow = couponUserMapper.insertSelective(couponUser);
        return affectedRow;
    }


    public void updateCouponStatus() {
        CouponExample couponExample = new CouponExample();
        couponExample.createCriteria().andStatusEqualTo((short) 0);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        for (Coupon coupon : coupons) {
            if (!judgeDate(coupon)) {
                Coupon coupon1 = new Coupon();
                coupon1.setStatus((short) 1);
                coupon1.setId(coupon.getId());
                couponMapper.updateByPrimaryKeySelective(coupon1);
            }
        }
    }

    public boolean judgeDate(Coupon coupon) {
        if (coupon.getTimeType() == 1) {
            //按日期
            if (coupon.getEndTime().getTime() > new Date().getTime())
                return true;
            return false;
        } else {
            //按天数
            long endTime = coupon.getDays() * 24 * 60 * 60 * 1000 + coupon.getAddTime().getTime();
            if (endTime > new Date().getTime())
                return true;
            return false;
        }
    }

    public void updateCouponUserStatus() {
        CouponUserExample couponUserExample = new CouponUserExample();
        couponUserExample.createCriteria().andStatusEqualTo((short) 0);
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(couponUserExample);
        for (CouponUser couponUser : couponUsers) {
            if (couponUser.getEndTime().getTime() < new Date().getTime()) {
                CouponUser couponUser1 = new CouponUser();
                couponUser1.setId(couponUser.getId());
                couponUser1.setStatus((short) 2);
                couponUserMapper.updateByPrimaryKeySelective(couponUser1);
            }
        }
    }

}
